package com.dycx.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dycx.common.vendor.oss.AliyunOss;
import com.dycx.common.vendor.oss.OssConfig;
import com.dycx.system.converter.RegionConverter;
import com.dycx.system.mapper.RegionMapper;
import com.dycx.system.dto.RegionDTO;
import com.dycx.system.entity.RegionDO;
import com.dycx.system.enums.RegionLevelEnum;
import com.dycx.system.service.ConfigService;
import com.dycx.system.service.RegionService;
import com.dycx.system.vo.RegionInfoVO;
import com.dycx.system.vo.RegionVO;
import com.dycx.common.vendor.map.vo.gaode.DistrictsVO;
import com.dycx.system.vo.SystemConfig;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@AllArgsConstructor
public class RegionServiceImpl extends ServiceImpl<RegionMapper, RegionDO> implements RegionService {
    private ConfigService configService;

    @Override
    public Boolean delete(int id) {
        return removeById(id);
    }

    /**
     * 添加
     *
     * @param regionDto
     * @return
     */
    @Override
    public Boolean create(RegionDTO regionDto) {
        if (ObjectUtil.isNotNull(load(regionDto.getCode()))) {
            throw new RuntimeException("地区编码已存在，请重新输入");
        }

        RegionDO regionDO = RegionConverter.dtoToEntity(regionDto);
        return save(regionDO);
    }

    /**
     * 添加/修改
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean edit(RegionDTO dto) {
        LambdaQueryWrapper<RegionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RegionDO::getCode, dto.getCode());
        wrapper.ne(RegionDO::getId, dto.getId());

        if (getOne(wrapper) != null) {
            throw new RuntimeException("地区编码已存在，请重新输入");
        }

        if (!updateById(RegionConverter.dtoToEntity(dto))) throw new RuntimeException("修改失败");

        return true;
    }

    @Override
    public RegionVO load(int code) {
        LambdaQueryWrapper<RegionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RegionDO::getCode, code);
        return RegionConverter.entityToVo(getOne(wrapper));
    }

    @Override
    public RegionVO load(String name) {
        LambdaQueryWrapper<RegionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RegionDO::getName, name);
        wrapper.last("limit 1");
        return RegionConverter.entityToVo(getOne(wrapper));
    }

    @Override
    public RegionVO load(String cityName, String districtName, String streetName) {
        try {
            RegionVO cityVO = load(cityName);

            LambdaQueryWrapper<RegionDO> wrapper = new LambdaQueryWrapper<>();
            if (ObjectUtil.isNotNull(cityVO)) {
                wrapper.eq(RegionDO::getParentCode, cityVO.getCode());
            }
            wrapper.eq(RegionDO::getName, districtName);
            wrapper.last("limit 1");
            RegionDO regionDO = getOne(wrapper);
            if (ObjectUtil.isNull(regionDO)) return null;

            LambdaQueryWrapper<RegionDO> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(RegionDO::getParentCode, regionDO.getCode());
            wrapper2.eq(RegionDO::getName, streetName);
            wrapper2.last("limit 1");

            return RegionConverter.entityToVo(getOne(wrapper2));
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public String[] getRegionIdPath(int code) {
        List<RegionVO> list = this.getRegionPath(code);

        String[] idArr = new String[3];
        int i = 0;
        for (RegionVO item : list) {
            idArr[i] = item.getCode().toString();
            i++;
        }

        return idArr;
    }

    /**
     * 获取地区级别对象
     *
     * @param code
     * @return
     */
    @Override
    public List<RegionVO> getRegionPath(int code) {
        List<RegionVO> list = new ArrayList<>();

        RegionVO region = this.load(code);
        if (!RegionLevelEnum.PROVINCE.getCode().equals(region.getLevel())) {
            list.addAll(getRegionPath(region.getParentCode()));
        }

        list.add(region);

        return list;
    }

    /**
     * 获取地区完整路径
     *
     * @param code
     * @param joinStr
     * @return
     */
    @Override
    public String getRegionDetailName(Integer code, String joinStr) {
        String result = "";

        RegionVO regionVO = load(code);
        result = regionVO.getName();
        if (!RegionLevelEnum.PROVINCE.getCode().equals(regionVO.getLevel())) {
            result = this.getRegionDetailName(regionVO.getParentCode(), joinStr) + joinStr + result;
        }

        return result;
    }

    /**
     * 获取子级列表
     *
     * @param parentCode
     * @return
     */
    @Override
    public List<RegionVO> getChildList(Integer parentCode) {
        LambdaQueryWrapper<RegionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RegionDO::getParentCode, parentCode);
        wrapper.orderByAsc(RegionDO::getCode);

        return RegionConverter.entityToVoList(list(wrapper));
    }

    /**
     * 同步高德数据
     */
    @Override
    public void syncAMapData(List<DistrictsVO> regionList, Integer parentId) {

//        for (int i = 0; i < regionList.size(); i++) {
//            GaoDeRegionDTO item = regionList.get(i);
//
//            List<String> center = StrUtil.split(item.getCenter(), ',');
//            if (item.getLevel().equals(RegionLevelEnum.STREET.getCode())) {
//                String s = i < 10 ? "0" : "";
//                String newAdCode = item.getAdcode() + s + i;
//                item.setAdcode(Integer.parseInt(newAdCode));
//            }
//
//            RegionDO regionDO = new RegionDO();
//            regionDO.setId(item.getAdcode());
//            regionDO.setParentId(parentId);
//            regionDO.setName(item.getName());
//            regionDO.setLevel(item.getLevel());
//            regionDO.setLng(center.get(0));
//            regionDO.setLat(center.get(1));
//
//            save(regionDO);
//
//            if (item.getDistricts().size() > 0) {
//                syncAMapData(item.getDistricts(), item.getAdcode());
//            }
//        }
    }

    /**
     * 查询地区完整信息
     *
     * @param object
     * @return
     */
    @Override
    public <T> T replenish(T object) {
        RegionInfoVO vo = BeanUtil.toBean(object, RegionInfoVO.class);

        // 省
        if (ObjectUtil.isNull(vo.getProvinceCode()) && StrUtil.isNotBlank(vo.getProvinceName())) {
            RegionVO regionVO = load(vo.getProvinceName());
            if (ObjectUtil.isNotNull(regionVO)) {
                vo.setProvinceCode(regionVO.getCode());
            }
        }

        // 市
        if (ObjectUtil.isNull(vo.getCityCode()) && StrUtil.isNotBlank(vo.getCityName())) {
            RegionVO regionVO = load(vo.getCityName());
            if (ObjectUtil.isNotNull(regionVO)) {
                vo.setCityCode(regionVO.getCode());
            }
        }

        // 区/县
        if (ObjectUtil.isNull(vo.getDistrictCode()) && StrUtil.isNotBlank(vo.getDistrictName())) {
            RegionVO regionVO = load(vo.getDistrictName());
            if (ObjectUtil.isNotNull(regionVO)) {
                vo.setDistrictCode(regionVO.getCode());
            }
        }

        // 街道/镇
        if (ObjectUtil.isNull(vo.getStreetCode()) && StrUtil.isNotBlank(vo.getStreetName())) {
            LambdaQueryWrapper<RegionDO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ObjectUtil.isNotNull(vo.getDistrictCode()), RegionDO::getParentCode, vo.getDistrictCode());
            wrapper.like(RegionDO::getName, vo.getStreetName());
            wrapper.last("limit 1");
            RegionDO regionDO = getOne(wrapper);
            if (ObjectUtil.isNotNull(regionDO)) {
                vo.setStreetCode(regionDO.getCode());
            }
        }

        if (ObjectUtil.isNull(vo.getProvinceCode())) {
            if (ObjectUtil.isNotEmpty(vo.getStreetCode())) {
                List<RegionVO> regionVOList = getRegionPath(vo.getStreetCode());
                if (ObjectUtil.isNotEmpty(regionVOList) && regionVOList.size() == 4) {
                    vo.setProvinceCode(regionVOList.get(0).getCode());
                    vo.setProvinceName(regionVOList.get(0).getName());

                    vo.setCityCode(regionVOList.get(1).getCode());
                    vo.setCityName(regionVOList.get(1).getName());

                    vo.setDistrictCode(regionVOList.get(2).getCode());
                    vo.setDistrictName(regionVOList.get(2).getName());

                    vo.setStreetCode(regionVOList.get(3).getCode());
                    vo.setStreetName(regionVOList.get(3).getName());
                }
            } else if (ObjectUtil.isNotEmpty(vo.getDistrictCode())) {
                List<RegionVO> regionVOList = getRegionPath(vo.getDistrictCode());
                if (ObjectUtil.isNotEmpty(regionVOList) && regionVOList.size() == 3) {
                    vo.setProvinceCode(regionVOList.get(0).getCode());
                    vo.setProvinceName(regionVOList.get(0).getName());

                    vo.setCityCode(regionVOList.get(1).getCode());
                    vo.setCityName(regionVOList.get(1).getName());

                    vo.setDistrictCode(regionVOList.get(2).getCode());
                    vo.setDistrictName(regionVOList.get(2).getName());
                }
            } else if (ObjectUtil.isNotEmpty(vo.getCityCode())) {
                List<RegionVO> regionVOList = getRegionPath(vo.getCityCode());
                if (ObjectUtil.isNotEmpty(regionVOList) && regionVOList.size() == 2) {
                    vo.setProvinceCode(regionVOList.get(0).getCode());
                    vo.setProvinceName(regionVOList.get(0).getName());

                    vo.setCityCode(regionVOList.get(1).getCode());
                    vo.setCityName(regionVOList.get(1).getName());
                }
            }
        }

        BeanUtil.copyProperties(vo, object);

        return object;
    }

    /**
     * 缓存地区数据
     *
     * @return
     */
    @Override
    public Boolean cacheRegion(String level) {
        String json = JSON.toJSONString(cacheRegion(0, level));
        AliyunOss.uploadString("static/region_" + level + ".json", json);
        return true;
    }

    public List<Map<String, Object>> cacheRegion(Integer parentCode, String level) {
        List<Map<String, Object>> list = new ArrayList<>();

        List<RegionVO> regionList = this.getChildList(parentCode);
        regionList.forEach(item -> {
            Map<String, Object> map = new HashMap<>();
            map.put("label", item.getName());
            map.put("value", item.getCode());
            if (!item.getLevel().equals(level)) {
                map.put("children", cacheRegion(item.getCode(), level));
            }

            list.add(map);
        });

        return list;
    }

}



















